package com.hzncc.flowable_diboot.payment.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.diboot.core.entity.Dictionary;
import com.diboot.core.exception.BusinessException;
import com.diboot.core.holder.ThreadLocalHolder;
import com.diboot.core.service.impl.DictionaryServiceExtImpl;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.vo.JsonResult;
import com.diboot.core.vo.LabelValue;
import com.diboot.iam.entity.BaseLoginUser;
import com.diboot.iam.util.IamSecurityUtils;
import com.diboot.notification.config.Cons;
import com.diboot.notification.entity.Message;
import com.hzncc.flowable_diboot.entity.SapCustomer;
import com.hzncc.flowable_diboot.excel.service.MultiSheetExcelImportService;
import com.hzncc.flowable_diboot.payment.entity.PaymentContract;
import com.hzncc.flowable_diboot.payment.excel.listener.PaymentRegisterImportListener;
import com.hzncc.flowable_diboot.payment.excel.model.PaymentRegisterImportModel;
import com.hzncc.flowable_diboot.payment.service.PaymentContractService;
import com.hzncc.flowable_diboot.payment.vo.PaymentContractDetailVO;
import com.hzncc.flowable_diboot.payment.vo.PaymentRegisterDetailVO;
import com.hzncc.flowable_diboot.rabbitmq.service.impl.SendMessageService;
import com.hzncc.flowable_diboot.service.SapCustomerService;
import com.hzncc.flowable_diboot.util.ConstantUtil;
import com.hzncc.flowable_diboot.util.MessageCons;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.diboot.core.service.impl.BaseServiceImpl;

import com.hzncc.flowable_diboot.payment.entity.PaymentRegister;
import com.hzncc.flowable_diboot.mapper.PaymentRegisterMapper;
import com.hzncc.flowable_diboot.payment.service.PaymentRegisterService;

import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 回款登记 相关Service实现类
 *
 * @author MyName
 * @version 1.0
 * @date 2024-10-15
 * Copyright © MyCorp
 */
@Slf4j
@Service
public class PaymentRegisterServiceImpl extends BaseServiceImpl<PaymentRegisterMapper, PaymentRegister> implements PaymentRegisterService {
    @Resource
    private SendMessageService sendMessageService;

    @Resource
    private MultiSheetExcelImportService multiSheetExcelImportService;

    @Resource
    private DictionaryServiceExtImpl dictionaryService;

    @Autowired
    private SapCustomerService sapCustomerService;

    @Override
    @Transactional
    public boolean createPaymentRegister(PaymentRegister paymentRegister) {
        BaseLoginUser currentUser = IamSecurityUtils.getCurrentUser();
        BigDecimal receivedAmount = new BigDecimal(0);
        BigDecimal unclaimedAmount = paymentRegister.getPaymentAmount();
        paymentRegister.setReceivedAmount(receivedAmount).setUnclaimedAmount(unclaimedAmount)
                .setCerted("0").setLocked("0").setStatus("10");
        if(StringUtils.isEmpty(paymentRegister.getCategory())){
            throw new BusinessException("请选择回款类别");
        }
//        Map<String, LabelValue> paymentBank = dictionaryService.getValue2ItemMap("paymentBank");
//        LabelValue labelValue = paymentBank.get(paymentRegister.getPaymentItem());
//        String bankName = labelValue.getLabel().split("#")[1];
//        paymentRegister.setBankName(bankName);
        boolean success = this.createEntity(paymentRegister);
        String copyRead = paymentRegister.getCopyRead();
        if (StringUtils.isNotEmpty(copyRead)) {
            String[] split = copyRead.split(",");
            List<String> copyReadList = Arrays.asList(split);
            for (String uid : copyReadList) {
                // 发送传阅消息
                sendMessageService.sendRetainedMessage(new Message().setChannel(Cons.MESSAGE_CHANNEL.SYS_MSG.name())
                        .setTitle(MessageCons.PAYMENT_REGISTER_TITLE)
                        .setReceiver(uid).setSender(currentUser.getId())
                        .setContent(String.format(ConstantUtil.PAYMENT_REGISTER_COPY_READ, currentUser.getDisplayName(), paymentRegister.getCustomerName()))
                        .setStatus(Cons.MESSAGE_STATUS.DELIVERY.name()).setAppModule(ConstantUtil.MODEL_PAYMENT).setTemplateId("")
                        .setBusinessCode(MessageCons.PAYMENT_REGISTER_CODE).setBusinessType(MessageCons.PAYMENT_REGISTER_TYPE)
                        .setChannel(Cons.MESSAGE_CHANNEL.SYS_MSG.name()));
            }
        }
        String salesCopyRead = paymentRegister.getSalesCopyRead();
        if (StringUtils.isNotEmpty(salesCopyRead)) {
            String[] split = salesCopyRead.split(",");
            List<String> salesCopyReadList = Arrays.asList(split);
            for (String uid : salesCopyReadList) {
                // 发送传阅消息
                sendMessageService.sendRetainedMessage(new Message().setChannel(Cons.MESSAGE_CHANNEL.SYS_MSG.name())
                        .setTitle(MessageCons.PAYMENT_REGISTER_TITLE)
                        .setReceiver(uid).setSender(currentUser.getId())
                        .setContent(String.format(ConstantUtil.PAYMENT_REGISTER_COPY_READ, currentUser.getDisplayName(), paymentRegister.getCustomerName()))
                        .setStatus(Cons.MESSAGE_STATUS.DELIVERY.name()).setAppModule(ConstantUtil.MODEL_PAYMENT).setTemplateId("")
                        .setBusinessCode(MessageCons.PAYMENT_REGISTER_CODE).setBusinessType(MessageCons.PAYMENT_REGISTER_TYPE)
                        .setChannel(Cons.MESSAGE_CHANNEL.SYS_MSG.name()));
            }
        }
        return success;
    }

    @Override
    @Transactional
    public JsonResult<?> batchImportPaymentRegister(MultipartFile file, Map<String, Object> params) throws Exception {
        HashMap<String, String> errorResult = new HashMap<>();
        String sheetName = (String) params.get("sheetName");
        ExcelReader reader = EasyExcel.read(file.getInputStream()).build();
        List<ReadSheet> readSheets = reader.excelExecutor().sheetList();
        List<String> sheetNames = readSheets.stream().map(ReadSheet::getSheetName).collect(Collectors.toList());
        if (!sheetNames.contains(sheetName)) {
            throw new BusinessException("无" + sheetName + "sheet页");
        }
        List<PaymentRegisterImportModel> list = multiSheetExcelImportService.readSheet(file, PaymentRegisterImportModel.class, PaymentRegisterImportListener.class, 1, sheetName);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        List<PaymentRegisterDetailVO> paymentRegisterDetailVOList = new ArrayList<>();
        for (PaymentRegisterImportModel model : list){
            if (model.getPaymentTime() == null){
                errorResult.put(model.getCustomerName(), "导入失败,回款时间输入有误,应输入例如1997-01-01时间格式");
                continue;
            }
            if (model.getPaymentAmount() == null || model.getPaymentAmount().compareTo(BigDecimal.ZERO) < 0) {
                errorResult.put(model.getCustomerName(), "导入失败,回款金额输入有误");
                continue;
            }
            if (StringUtils.isEmpty(model.getBankName())) {
                errorResult.put(model.getCustomerName(), "导入失败,银行列输入有误");
                continue;
            }
            PaymentRegisterDetailVO paymentRegisterDetailVO = new PaymentRegisterDetailVO();
            paymentRegisterDetailVO.setPaymentTime(model.getPaymentTime().atStartOfDay());
            paymentRegisterDetailVO.setCustomerName(model.getCustomerName());
            paymentRegisterDetailVO.setBankName(model.getBankName());
            paymentRegisterDetailVO.setPaymentAmount(model.getPaymentAmount());
            paymentRegisterDetailVO.setRemark(model.getRemark());
            paymentRegisterDetailVOList.add(paymentRegisterDetailVO);
        }
        List<Dictionary> paymentBackDict = dictionaryService.getEntityListByType("paymentBank");
//        List<String> itemNames = paymentBackDict.stream().map(Dictionary::getItemName).collect(Collectors.toList());
        HashMap<String, String> bankMap = new HashMap<>();
        paymentBackDict.forEach(item -> {
            String paymentItem = item.getItemValue();
            String bankName = item.getItemName().split("#")[1];
            bankMap.put(bankName, paymentItem);
        });
        List<String> customerCodes = paymentRegisterDetailVOList.stream()
                .map(PaymentRegisterDetailVO::getCustomerCode)
                .distinct()
                .toList();
        if (!customerCodes.isEmpty()) {
            List<SapCustomer> sapCustomers = sapCustomerService.getEntityList(sapCustomerService.lambdaQuery()
                    .select(SapCustomer::getSapNo, SapCustomer::getCustomerId, SapCustomer::getName)
                    .in(SapCustomer::getSapNo, customerCodes));
            if (!sapCustomers.isEmpty()) {
                Map<String, String> sapCustomerIdMap = new HashMap<>();
                Map<String, String> sapCustomerNameMap = new HashMap<>();
                for (SapCustomer sapCustomer : sapCustomers) {
                    sapCustomerIdMap.put(sapCustomer.getSapNo(), sapCustomer.getCustomerId());
                    sapCustomerNameMap.put(sapCustomer.getSapNo(), sapCustomer.getName());
                }
                for (PaymentRegister paymentRegister : paymentRegisterDetailVOList) {
                    paymentRegister.setSapCustomerId(sapCustomerIdMap.get(paymentRegister.getCustomerCode()));
                    paymentRegister.setCustomerName(sapCustomerNameMap.get(paymentRegister.getCustomerCode()));
                }
            }
        }
        for (PaymentRegisterDetailVO item : paymentRegisterDetailVOList) {
            String backName = item.getBankName();
            if (bankMap.containsKey(backName)) {
                item.setPaymentItem(bankMap.get(backName)).setType("20");
            } else if ("银承".equals(backName)) {
                item.setType("30").setBillNum(item.getRemark()).setBankName("");
            } else if ("商承".equals(backName)) {
                item.setType("40").setBillNum(item.getRemark()).setBankName("");
            } else {
                errorResult.put(item.getCustomerName(), "导入失败,银行列输入有误");
                continue;
            }
            item.setCategory("10").setReceivedAmount(new BigDecimal(0)).setUnclaimedAmount(item.getPaymentAmount())
                    .setCerted("0").setLocked("0").setStatus("10");
        }
        //如果存在，一条失败，其他也不录入
        if (!errorResult.isEmpty()) {
            return JsonResult.OK(errorResult);
        }
        this.createEntities(paymentRegisterDetailVOList);
        return JsonResult.OK();
    }
}